package com.demo.java.concurrent.thread;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class GuardedSuspensionTimeoutTest {
    public static void main(String[] args) throws InterruptedException {
        GuardedObject<String> guardedObject = new GuardedObject();
        new Thread(() -> {
            String obj = guardedObject.get(5000);
            log.info("guarded obj: " + obj);
        }, "t1").start();
        new Thread(() -> {
            try {
                log.info("do some business");
                Thread.sleep(10000);
            } catch (InterruptedException e) {}
            guardedObject.complete("hello");
        }, "t2").start();
        Thread.sleep(15000);
    }
    private static class GuardedObject<T> {
        private T obj;
        public T get(long timeout) {
            // 1. 临界资源保护，保证共享资源在多线程下可见，作用类似volatile
            // 2. wait方法需要一个监视器对象
            long start = System.currentTimeMillis();
            synchronized (this) {
                while (obj == null) {
                    long interval = System.currentTimeMillis() - start;
                    long lastWait = timeout - interval;
                    if (lastWait <= 0) {
                        log.info("wait timeout return null");
                        break ;
                    }
                    try {
                        this.wait(lastWait);
                    } catch (InterruptedException e) {
                        log.info("===== wait interrupted.", e);
                    }
                }
            }
            return this.obj;
        }
        public void complete(T obj) {
            synchronized (this) {
                this.obj = obj;
                this.notifyAll();
            }
        }
    }
}
